// Author: Domien Nowicki

#include "CellSideWidget.h"
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QStyleOption>

CellSideWidget::CellSideWidget(Cell::Side nSide, QObject *parent): QObject(parent), side(nSide), highlight(false)
{
	bounds = QRectF(0, 0, ITEMSIZE, ITEMSIZE);

	setAcceptsHoverEvents(true);
	SetupPath();
	setZValue(ITEMZ);
}



CellSideWidget::~CellSideWidget()
{
}

QRectF CellSideWidget::boundingRect() const
{
	return bounds;
}

QPainterPath CellSideWidget::shape() const
{
	return path;
}

void CellSideWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
	QColor color;

	// Clip to item path
	painter->setClipPath(path);

	// No texture selected?
	if (sideColor.IsTransparent())
	{
		// Draw alternating white/gray squares for this side
		int even = 1;
		for(unsigned int cy=0; cy<8; cy++)
		{
			even ^= 1;
			for(unsigned int cx=0; cx<8; cx++)
			{
				QColor color;

				if (even)
				{
					color = Qt::gray;
				}
				else
				{
					color = Qt::white;
				}

				color.setAlpha(130);
				painter->setPen(Qt::NoPen);
				painter->setBrush(color);

				even ^= 1;

				painter->drawRect(cx*8, cy*8, 8, 8);
			}
		}

		painter->setPen(Qt::white);
		painter->setBrush(Qt::NoBrush);
		painter->drawPath(path);
	}
	else
	{
		// Otherwise color the side in the selected usercolor
		color = QColor(sideColor.GetRed(), sideColor.GetGreen(), sideColor.GetBlue());

		painter->setPen(Qt::white);
		painter->setBrush(color);
		painter->drawPath(path);
	}

	// And highlight with inverted color
	if (highlight)
	{
		color.setRed( 255 - color.red());
		color.setGreen( 255 - color.green());
		color.setBlue( 255 - color.blue());
		color.setAlpha(100);

		painter->setBrush(color);
		painter->drawPath(path);
	}

}

void CellSideWidget::hoverEnterEvent(QGraphicsSceneHoverEvent *e)
{
 	highlight = true;

	update();
}

void CellSideWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *e)
{
	highlight = false;

	update();
}

void CellSideWidget::mousePressEvent(QGraphicsSceneMouseEvent *e)
{
	emit clicked(this);
}



void CellSideWidget::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
{
}

void CellSideWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *e)
{
}

// Setup the cell side's path
void CellSideWidget::SetupPath()
{
	switch(side)
	{
		case Cell::FRONT:
			path.moveTo( QPointF(0, ITEMSIZE) );
			path.lineTo(SIDEWIDTH, ITEMSIZE-SIDEWIDTH);
			path.lineTo(ITEMSIZE-SIDEWIDTH, ITEMSIZE-SIDEWIDTH);
			path.lineTo(ITEMSIZE, ITEMSIZE);
			path.lineTo(0, ITEMSIZE);
		break;

		case Cell::BACK:
			path.moveTo( QPointF(0, 0) );
			path.lineTo(SIDEWIDTH, SIDEWIDTH);
			path.lineTo(ITEMSIZE-SIDEWIDTH, SIDEWIDTH);
			path.lineTo(ITEMSIZE, 0);
			path.lineTo(0, 0);
		break;

		case Cell::LEFT:
			path.moveTo( QPointF(0, 0) );
			path.lineTo(SIDEWIDTH, SIDEWIDTH);
			path.lineTo(SIDEWIDTH, ITEMSIZE-SIDEWIDTH);
			path.lineTo(0, ITEMSIZE);
			path.lineTo(0, 0);
		break;

		case Cell::RIGHT:
			path.moveTo( QPointF(ITEMSIZE, 0) );
			path.lineTo(ITEMSIZE, ITEMSIZE);
			path.lineTo(ITEMSIZE-SIDEWIDTH, ITEMSIZE-SIDEWIDTH);
			path.lineTo(ITEMSIZE-SIDEWIDTH, SIDEWIDTH);
			path.lineTo(ITEMSIZE, 0);
		break;

		case Cell::CEILING:
			path.moveTo( QPointF(SIDEWIDTH, SIDEWIDTH) );
			path.lineTo(ITEMSIZE-SIDEWIDTH, SIDEWIDTH);
			path.lineTo(ITEMSIZE-SIDEWIDTH, ITEMSIZE/2);
			path.lineTo(SIDEWIDTH, ITEMSIZE/2);
			path.lineTo(SIDEWIDTH, SIDEWIDTH);
		break;

		case Cell::FLOOR:
			path.moveTo( QPointF(SIDEWIDTH, ITEMSIZE-SIDEWIDTH) );
			path.lineTo(SIDEWIDTH, ITEMSIZE/2);
			path.lineTo(ITEMSIZE-SIDEWIDTH, ITEMSIZE/2);
			path.lineTo(ITEMSIZE-SIDEWIDTH, ITEMSIZE-SIDEWIDTH);
			path.lineTo(SIDEWIDTH, ITEMSIZE-SIDEWIDTH);
		break;
	}
}

void CellSideWidget::SetSideColor(const Pixel& color)
{
	sideColor = color;

	update();
}

const Pixel& CellSideWidget::GetSideColor() const
{
	return sideColor;
}

Cell::Side CellSideWidget::GetSide() const
{
	return side;
}
